Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at ways to improve our JavaScript code.
Call Superclass Constructors from Subclass Constructors
To create a constructor that inherits from a parent constructor, then we need to call the superclass constructor within the subclass constructor.
For instance, we can write:
function Person(name) {
this.name = name;
}
Person.prototype.toString = function() {
return `Person ${this.name}`;
}
function Actor(name, role) {
Person.call(this, name);
this.role = role;
}
Actor.prototype = Object.create(Person.prototype);
Actor.prototype.constructor = Actor;
We create the Person
constructor that servers the superclass constructor.
The instance methods are in the prototype
property.
The Actor
subclass is created by calling the Person
constructor and then set its own state.
Then we create the prototype by using Object.create
so that all the methods from Person
are inherited.
Then we set the constructor
to Actor
so that if we use instanceof
with an Actor
instance like:
new Actor('james', 'main') instanceof Actor
Then that should return true
.
We can call Person
methods in an Actor
instance because of the inheritance.
And we can override them if we wish.
So if we have:
const str = new Actor('james', 'main').toString()
that works and we get 'Person james’
as the value of str
.
A less error-prone way to create superclasses and subclasses is using the class syntax.
For instance, we can write:
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `Person ${this.name}`;
}
}
class Actor extends Person {
constructor(name, role) {
super(name);
this.role = role;
}
}
instead of what we had before.
They’re the same.
It’s just that the class version is shorter and way less chance of making mistakes.
super
replaces the Person.call
method call.
extends
is the same as using Object.create
and setting the constructor
property.
So the class syntax should be used since it’s introduced, but we’ve to know that underneath, is still prototypes and constructors.
Never Reuse Superclass Property Names
We shouldn’t use superclass property names.
For instance, if we have:
function Person(name) {
this.name = name;
}
Person.prototype.toString = function() {
return `Person ${this.name}`;
}
function Actor(name, role) {
Person.call(this, name);
this.name = name;
this.role = role;
}
Actor.prototype = Object.create(Person.prototype);
Actor.prototype.constructor = Actor;
then we used name
in both Actor
and Person
.
This will create conflict between the 2.
Subclasses should be aware of all properties used by superclasses.
So we shouldn’t redefine properties that are in the superclass.
With the class syntax, we can just use the super
object to refer to the instance properties of a superclass.
Conclusion
The class syntax lets us avoid many mistakes that we can create with subclass and superclasses.
Also, we shouldn’t have the same instance property names in a subclass and superclass.